from rest_framework.response import Response
from rest_framework.generics import ListAPIView, RetrieveAPIView
from rest_framework.views import APIView


from .models import CourseDirection, CourseCategory, Course, Teacher
from .serializers import CourseDirectionModelSerializer, CourseCategoryModelSerializer, CourseInfoModelSerializer

from rest_framework.filters import OrderingFilter
from .paginations import CourseListPageNumberPagination
from drf_haystack.viewsets import HaystackViewSet
from drf_haystack.filters import HaystackFilter
from .serializers import CourseIndexHaystackSerializer, CourseRetrieveModuleSerializer
from django_redis import get_redis_connection
from datetime import datetime, timedelta
import constants

# Create your views here.
class CourseDirectionListAPIView(ListAPIView):
    """学习方向"""
    queryset = CourseDirection.objects.filter(is_show=True, is_delete=False).order_by("orders","id")
    serializer_class = CourseDirectionModelSerializer
    pagination_class = None


class CourseCategoryListAPIView(ListAPIView):
    """学习分类"""

    serializer_class = CourseCategoryModelSerializer
    pagination_class = None

    def get_queryset(self):

        queryset = CourseCategory.objects.filter(is_show=True, is_delete=False)
        # 如果direction为0，则表示查询所有的课程分类，如果大于0，则表示按学习方向来查找课程分类
        # 类视图中，获取路由参数  self.kwargs
        direction = int(self.kwargs.get("direction", 0))
        if direction > 0:
            queryset = queryset.filter(direction=direction)
        return queryset.order_by("orders", "id").all()





# /courses/(方向)/(分类)/  课程列表
# /courses/0/0/  全部课程列表
# /courses/1/0/  direction=1的学习方向下课程列表
# /courses/1/3/  学习方向direction=1 and 课程分类=category=3的课程列表
class CourseListAPIView(ListAPIView):
    """课程列表"""
    serializer_class = CourseInfoModelSerializer
    filter_backends = [OrderingFilter, ]
    ordering_fields = ['id', 'students', 'orders']
    pagination_class = CourseListPageNumberPagination

    def get_queryset(self):
        queryset = Course.objects.filter(is_show=True, is_delete=False)
        direction = int(self.kwargs.get("direction", 0))
        category = int(self.kwargs.get("category", 0))

        # 只有在学习方向大于0的情况下才进行学习方向的过滤
        if direction > 0:
            queryset = queryset.filter(direction=direction)

        # 只有在课程分类大于0的情况下才进行课程分类的过滤
        if category > 0:
            queryset = queryset.filter(category=category)

        return queryset.order_by("orders","id").all()


class CourseSearchViewSet(HaystackViewSet):
    # 指定本次搜索的最终真实数据的ORM模型
    index_models = [Course]
    serializer_class = CourseIndexHaystackSerializer
    filter_backends = [OrderingFilter, HaystackFilter]
    ordering_fields = ('id', 'students', 'orders')
    pagination_class = CourseListPageNumberPagination

    def list(self, request, *args, **kwargs):
        redis = get_redis_connection("hot_word")
        text = request.query_params.get("text")
        if text:
            key = f"{constants.DEFAULT_HOT_WORD}:{datetime.now().strftime('%Y:%m:%d')}"
            is_exists = redis.exists(key)
            # zincrby course 1 mongodb
            redis.zincrby(key, 1, text)
            if not is_exists:
                redis.expire(key, constants.HOT_WORD_EXPIRE  * 24 * 3600)

        return super().list(request, *args, **kwargs)

class HotWordAPIView(APIView):
    """搜索热词"""
    def get(self, request):
        redis = get_redis_connection("hot_word")
        # 获取最近指定天数的热词的key
        date_list = []
        for i in range(0, constants.HOT_WORD_EXPIRE):
            day = datetime.now() - timedelta(days=i)
            key = f"{constants.DEFAULT_HOT_WORD}:{day.year}:{day.month}:{day.day}"
            date_list.append(key)

        # 先删除原有的统计最近几天的热搜词的有序统计集合
        redis.delete(constants.DEFAULT_HOT_WORD)
        # ZUNIONSTORE hot_word 7 "hot_word:2021:11:22" "hot_word:2021:11:21"  "hot_word:2021:11:20" "hot_word:2021:11:19" "hot_word:2021:11:18" "hot_word:2021:11:17" "hot_word:2021:11:16"
        # 根据date_list找到最近指定天数的所有集合，并完成并集计算，产生新的有序统计集合constants.DEFAULT_HOT_WORD
        redis.zunionstore(constants.DEFAULT_HOT_WORD, date_list, aggregate="sum")
        # 按分数store进行倒序显示排名靠前的指定数量的热词
        word_list = redis.zrevrange(constants.DEFAULT_HOT_WORD, 0, constants.HOT_WORD_LENGTH-1)
        return Response(word_list)



class CourseRetrieveAPIView(RetrieveAPIView):
    """课程详情信息"""
    queryset = Course.objects.filter(is_show=True, is_delete=False).all()
    serializer_class = CourseRetrieveModuleSerializer

